package com.regis.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.regis.comment.CodeMsg;
import com.regis.comment.GlobalException;
import com.regis.entity.db.Category;
import com.regis.entity.db.Dish;
import com.regis.entity.db.Setmeal;
import com.regis.entity.db.SetmealDish;
import com.regis.entity.dto.SetmealDto;
import com.regis.entity.vo.ResultVo;
import com.regis.service.CategoryService;
import com.regis.service.DishService;
import com.regis.service.SetmealDishService;
import com.regis.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 计算机系 ITAEM 纱雾休比我老婆
 * @Description 套餐界面接口
 * @date 2022/8/1 0:33
 */
@Slf4j
@RestController
@RequestMapping("/setmeal")
public class SetMealController {

    @Autowired
    private SetmealService setmealService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private DishService dishService;
    @Autowired
    private CacheManager cacheManager;

    /**
     * 新增套餐
     * @return
     */
    @CacheEvict(value = "setMeal",allEntries = true)
    @PostMapping
    public ResultVo<String> save(@RequestBody SetmealDto setmealDto){
        setmealService.saveWithDish(setmealDto);
        return ResultVo.success("新增套餐成功");
    }

    /**
     * 套餐信息分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Cacheable(value = "setMeal",key = "#page + '_' + #pageSize",condition = "#name == null",
            unless = "#result.data.records == null")
    @GetMapping("/page")
    public ResultVo<Page<SetmealDto>> page(int page, int pageSize, String name){
        //分页构造器对象
        Page<Setmeal> pageInfo = new Page<>(page,pageSize);
        Page<SetmealDto> dtoPage = new Page<>();

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(name != null,Setmeal::getName,name)
                .orderByDesc(Setmeal::getUpdateTime);

        setmealService.page(pageInfo,queryWrapper);

        BeanUtils.copyProperties(pageInfo,dtoPage,"records");

        List<Setmeal> setmeals = pageInfo.getRecords();

        HashSet<Long> set = new HashSet<>();
        ArrayList<Long> ids = new ArrayList<>();
        for(Setmeal s : setmeals){
            if(set.add(s.getCategoryId())){
                ids.add(s.getCategoryId());
            }
        }
        List<Category> categories = categoryService.listByIds(ids);
        HashMap<Long, String> map = new HashMap<>();
        for(Category c : categories){
            map.put(c.getId(),c.getName());
        }

        List<SetmealDto> setmealDtos = setmeals.stream().map((item) -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(item, setmealDto);
            setmealDto.setCategoryName(map.get(item.getCategoryId()));
            return setmealDto;
        }).collect(Collectors.toList());

        dtoPage.setRecords(setmealDtos);

        return ResultVo.success(dtoPage);
    }

    /**
     * 根据id删除套餐
     * @param ids
     * @return
     */
    @CacheEvict(value = "setMeal",allEntries = true)
    @DeleteMapping
    public ResultVo<String> delete(Long... ids){
        List<Setmeal> setmeals = setmealService.listByIds(Arrays.asList(ids));
        setmealService.delete(ids);
        return ResultVo.success("删除成功");
    }

    /**
     * 根据id修改套餐状态
     * @return
     */
    @CacheEvict(value = "setMeal",allEntries = true)
    @Transactional
    @PostMapping("/status/{type}")
    public ResultVo<String> status(@PathVariable int type,Long... ids){
        if(!Objects.equals(type,1)&&!Objects.equals(type,0)){
            return ResultVo.error("状态数值异常");
        }
        //若是起售，判断对应的菜品是否有停售
        if(type == 1){
            List<SetmealDish> setmealDishes =
                    setmealDishService.list(new LambdaQueryWrapper<SetmealDish>().in(SetmealDish::getSetmealId, Arrays.asList(ids)));
            HashSet<Long> dishIds = new HashSet<>();
            for(SetmealDish s : setmealDishes){
                dishIds.add(s.getDishId());
            }
            List<Dish> dishes =
                    dishService.list(new LambdaQueryWrapper<Dish>().in(Dish::getId, dishIds).eq(Dish::getStatus, 0));
            ArrayList<String> list = new ArrayList<>();
            for(Dish d : dishes){
                list.add(d.getName());
            }
            if(dishes.size() != 0){
                throw new GlobalException(new CodeMsg("餐品：" + list + "处于停售状态，套餐不可起售"));
            }
        }

        ArrayList<Setmeal> setmeals = new ArrayList<>();
        for(Long l : ids){
            Setmeal setmeal = new Setmeal();
            setmeal.setId(l);
            setmeal.setStatus(type);
            setmeals.add(setmeal);
        }
        setmealService.updateBatchById(setmeals);
        return ResultVo.success("修改成功");
    }

    /**
     * 根据id查询一条套餐信息
     * @param id
     * @return
     */
    @Cacheable(value = "setMeal",key = "#id+'_s'",unless = "#result.data == null ")
    @GetMapping("/{id}")
    public ResultVo<SetmealDto> get(@PathVariable Long id){
        return ResultVo.success(setmealService.get(id));
    }

    /**
     * 修改套餐信息
     * @param setmealDto
     * @return
     */
    @CacheEvict(value = "setMeal",allEntries = true)
    @PutMapping
    public ResultVo<String> update(@RequestBody SetmealDto setmealDto){
        setmealService.updateWithDish(setmealDto);
        return ResultVo.success("修改成功");
    }

    /**
     * 获取对应套餐分类下的套餐信息
     * @param setmeal
     * @return
     */
    @Cacheable(value = "setMeal",key = "#setmeal.categoryId + '_' + #setmeal.status",unless = "#result.data == null")
    @GetMapping("/list")
    public ResultVo<List<Setmeal>> list(Setmeal setmeal){
        List<Setmeal> list = null;

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(setmeal.getCategoryId()!=null,Setmeal::getCategoryId,setmeal.getCategoryId())
                .eq(setmeal.getStatus()!=null, Setmeal::getStatus,setmeal.getStatus());
        list = setmealService.list(queryWrapper);

        return ResultVo.success(list);
    }

    /**
     * 获取套餐的全部菜品,或菜品信息
     * @param id
     * @return
     */
    @Cacheable(value = "setMeal",key = "#id",unless = "#result.data == null")
    @GetMapping("/dish/{id}")
    public ResultVo<List<Dish>> getDishes(@PathVariable Long id){
        List<Dish> dishList = new ArrayList<>();
        Dish dish = dishService.getById(id);
        if(!Objects.isNull(dish)){
            dishList.add(dish);
            return ResultVo.success(dishList);
        }
        List<SetmealDish> setmealDishList = setmealDishService.list(new LambdaQueryWrapper<SetmealDish>().eq(id != null,
                SetmealDish::getSetmealId, id));
        List<Long> dishIds = setmealDishList.stream().map(SetmealDish::getDishId).collect(Collectors.toList());
        dishList = dishService.list(new LambdaQueryWrapper<Dish>().in(Dish::getId, dishIds));
        return ResultVo.success(dishList);
    }
}
